//
// Created by Administrator on 2021/5/5.
//
/*

你是一个专业的小偷，计划偷窃沿街的房屋。每间房内都藏有一定的现金，
 影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统，如果两间相邻的房屋在同一晚上被小偷闯入，系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组，计算你 不触动警报装置的情况下 ，一夜之内能够偷窃到的最高金额。

示例 1：
输入：[1,2,3,1]
输出：4
解释：偷窃 1 号房屋 (金额 = 1) ，然后偷窃 3 号房屋 (金额 = 3)。
   偷窃到的最高金额 = 1 + 3 = 4 。

示例 2：
输入：[2,7,9,3,1]
输出：12
解释：偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9)，接着偷窃 5 号房屋 (金额 = 1)。
   偷窃到的最高金额 = 2 + 9 + 1 = 12 。

提示：

1 <= nums.length <= 100
0 <= nums[i] <= 400

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/house-robber
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。*/
#include <vector>
#include <iostream>

using namespace std;

class Solution {
public:
    int rob(vector<int> &nums) {
        if (nums.empty()) return 0;
        auto size = nums.size();
        vector<pair<int, int>> dp(size + 1, pair<int, int>{0, 0});
        for (int i = 1; i <= size; ++i) {
            dp[i].first = dp[i - 1].second + nums[i-1];    // 偷这一家
            dp[i].second = max(dp[i - 1].first, dp[i - 1].second); // 不偷这一家
        }
        return max(dp.back().first, dp.back().second);
    }
};
class Solution2 {  // 题解1
public:
    int rob(vector<int>& nums) {
        if (nums.empty()) {
            return 0;
        }
        auto size = nums.size();
        if (size == 1) {
            return nums[0];
        }
        vector<int> dp = vector<int>(size, 0);
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        for (int i = 2; i < size; i++) {
            dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]); // 偷这家或者不偷这家
        }
        return dp[size - 1];
    }
    int rob2(vector<int>& nums) { // 只和前两家有关  用滚动数组
        if (nums.empty()) {
            return 0;
        }
        auto size = nums.size();
        if (size == 1) {
            return nums[0];
        }
        int first = nums[0], second = max(nums[0], nums[1]);  // 代替dp[i-2] dp[i-1]
        for (int i = 2; i < size; i++) {
            int temp = second;
            second = max(first + nums[i], second);
            first = temp;
        }
        return second;
    }

};


int main() {
    vector<int> v1{1, 2, 3, 1};
    vector<int> v2{2, 7, 9, 3, 1};
    Solution sol;
    cout << sol.rob(v1) << endl;
    cout << sol.rob(v2) << endl;
    return 0;
}